package com.csproj.system.service;

import com.csproj.basic.BasicService;
import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.security.SecurityUtils;
import com.csproj.system.domain.RoleInfo;
import com.csproj.system.domain.SysLogs;
import com.csproj.system.domain.UserInfo;
import com.csproj.system.repository.RoleInfoRepository;
import com.csproj.system.repository.SysLogsRepository;
import com.csproj.system.repository.UserInfoRepository;
import com.csproj.system.service.dto.SysLogsDTO;
import com.csproj.system.service.mapper.SysLogsMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.management.relation.Role;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Service Interface for managing SysLogs.
 */
@Service
@Transactional
public class SysLogsService extends BasicService<SysLogsDTO> {


    private final SysLogsRepository sysLogsRepository;

    private final SysLogsMapper sysLogsMapper;

    private final UserInfoRepository userInfoRepository;

    private final RoleInfoRepository roleInfoRepository;

    public SysLogsService(SysLogsRepository sysLogsRepository, SysLogsMapper sysLogsMapper,
                          UserInfoRepository userInfoRepository, RoleInfoRepository roleInfoRepository) {
        this.sysLogsRepository = sysLogsRepository;
        this.sysLogsMapper = sysLogsMapper;
        this.userInfoRepository = userInfoRepository;
        this.roleInfoRepository = roleInfoRepository;
    }

    /**
     * @param rentId   被操作对象ID
     * @param moduleType  操作模块
     * @param description 操作内容摘要
     * get 类型保存
     * @return
     */
    public SysLogsDTO saveForGet(String rentId,String description,String moduleType ){
        return sysLogsMapper.toDto(save(rentId,description,moduleType,SysLogs.OPERATION_TYPE_GET));
    }

    /**
     * delete 类型保存
     * @return
     */
    public SysLogsDTO saveForDelete(String rentId,String description,String moduleType ){
        return sysLogsMapper.toDto(save(rentId,description,moduleType,SysLogs.OPERATION_TYPE_DELETE));

    }

    /**
     * put 类型保存
     * @return
     */
    public SysLogsDTO saveForPut(String rentId,String description,String moduleType){
        return sysLogsMapper.toDto(save(rentId,description,moduleType,SysLogs.OPERATION_TYPE_PUT));

    }


    /**
     * post 类型保存
     * @return
     */
    public SysLogsDTO saveForPost(String rentId,String description,String moduleType){
        return sysLogsMapper.toDto(save(rentId,description,moduleType,SysLogs.OPERATION_TYPE_POST));
    }

    /**
     *
     * @param rentId
     * @param description
     * @param moduleType
     * @param type
     * @return
     */
    private SysLogs save(String rentId,String description,String moduleType,String type){
        SysLogs sysLogs = new SysLogs();
        sysLogs.setModuleType(moduleType);
        sysLogs.setDescription(description);
        sysLogs.setRendId(rentId);
        String currentUserId = SecurityUtils.getCurrentUserId();
        UserInfo userInfo = userInfoRepository.findOne(currentUserId);
        if(userInfo!=null)
        {
            Set<RoleInfo> roleInfos = userInfo.getRoleInfos();
            StringBuilder roleInfoIds = new StringBuilder(",");
            if(roleInfos!=null ){
                for (RoleInfo roleInfo : roleInfos) {
                    roleInfoIds.append(roleInfo.getId()).append(",");
                }
            }
            sysLogs.setRoleInfoIds(roleInfoIds.toString());
            sysLogs.setUserInfoId(currentUserId);
        }

        sysLogs.setCreationTime(ZonedDateTime.now());
        sysLogs.setCreatorUserId(currentUserId);
        sysLogs.setOperationType(type);
        sysLogs = sysLogsRepository.save(sysLogs);
        return sysLogs;
    }

    /**
     * 获取分页列表
     *
     * @param queryParams
     * @param pageable
     * @return
     */

    public BaseDTO findPageList(Map<String, Object> queryParams, Pageable pageable) {

        Page<SysLogs> result = sysLogsRepository.findPageList(queryParams, pageable);
        List<SysLogsDTO> sysLogDTOs = sysLogsMapper.toDto(result.getContent());
        extendsUserNameAndRoleName(sysLogDTOs);
        return BaseDTO.createBaseDTO(result).setFieldList(sysLogDTOs);
    }

    /**
     * extend username and rolename
     *
     * @param sysLogDTOs
     * @autor wangjf
     * @date
     */
    private void extendsUserNameAndRoleName(List<SysLogsDTO> sysLogDTOs) {

        List<String> userIds = sysLogDTOs.stream().map(l -> l.getUserInfoId()).collect(Collectors.toList());
        List<String> roleInfoIds = sysLogDTOs.stream().map(l->l.getRoleInfoIds()).collect(Collectors.toList());
        Set<String> roleIds = new HashSet<>();
        roleInfoIds.forEach(r-> {
            if (StringUtils.isNotBlank(r)) {
                roleIds.addAll(Arrays.asList(r.split(",")));
            }
        });
        List<RoleInfo> roleInfos = new ArrayList<>();
        if(roleIds.size()>0){
            roleInfos = roleInfoRepository.findByIds(roleIds.toArray(new String[roleIds.size()]));
        }
        final List<RoleInfo> roleInfoList = roleInfos;
        if (userIds.size() > 0) {
            Iterator<String> itr = userIds.iterator();
            while(itr.hasNext()){
                String u = itr.next();
                if(u == null){
                    itr.remove();
                }
            }
        }

        if (userIds.size() > 0) {
           // System.out.println(userIds.size());

            //System.out.println(userIds.size());
            List<UserInfo> userInfos = userInfoRepository.findByIds(userIds.toArray(new String[userIds.size()]));
            sysLogDTOs.forEach(log -> {
                if(StringUtils.isNotBlank(log.getUserInfoId()))
                {
                    UserInfo userInfo = userInfos.stream().filter(u -> log.getUserInfoId().equals(u.getId())).findFirst().orElse(new UserInfo());
                    log.setUserName(userInfo.getAccount());
                    String rolename = "";
                    String logRoleIds = log.getRoleInfoIds();
                    if(StringUtils.isNotBlank(logRoleIds)){
                        String [] logRoleIdsArr =    logRoleIds.split(",");
                        for (String i : logRoleIdsArr) {
                            RoleInfo role = roleInfoList.stream().filter(r->r.getId().equals(i)).findFirst().orElse(null);
                            if(role!=null){
                                rolename += role.getName();
                            }
                        }
                        log.setRoleName(rolename);
                    }
                }

            });
        }
    }
}
